const Cookies = require('js-cookie')
const {version} = require('../package')
const Wechat = typeof wx === 'undefined' ? {} : wx
const Alipay = typeof my === 'undefined' ? {} : my
const LocalStorage = typeof window === 'undefined' ? {} : ((window.localStorage) || {})
/**
 * 过期单位
 * */
const EXPIRE_UNIT = {
  SECOND: 0,
  MINUTE: 1,
  HOUR: 2,
  DAY: 3,
  MONTH: 4
}

/**
 * 过期实例
 * */
class Expire {
  /**
   * @param amount 数量
   * @param unit 单位 @see EXPIRE_UNIT
   * */
  constructor(amount, unit) {
    let offset = Math.max(1, parseFloat(amount))
    switch (unit || EXPIRE_UNIT.SECOND) {
      case EXPIRE_UNIT.MINUTE:
        offset *= 60
        break
      case EXPIRE_UNIT.HOUR:
        offset *= 3600
        break
      case EXPIRE_UNIT.DAY:
        offset *= 86400
        break
      case EXPIRE_UNIT.MONTH:
        offset *= 2592000
        break
    }
    this.expireDate = Date.now() + offset * 1000
  }
}

class Storage {
  constructor() {
    this.EXPIRE_UNIT = EXPIRE_UNIT
    this.Expire = Expire
    const supportWechatMiniProgram = typeof Wechat.getStorageSync === 'function' && typeof Wechat.setStorageSync === 'function' && typeof Wechat.removeStorageSync === 'function'
    const supportAlipayMiniProgram = typeof Alipay.getStorageSync === 'function' && typeof Alipay.setStorageSync === 'function' && typeof Alipay.removeStorageSync === 'function'
    const supportLocalStorage = typeof LocalStorage.getItem === 'function' && typeof LocalStorage.setItem === 'function' && typeof LocalStorage.removeItem === 'function'
    const supportWindowMemory = typeof window === 'object' && typeof window.location === 'object'
    const KEY_MEMORY = this.KEY_MEMORY = `__GLOBAL_CACHE_${version}__`

    this.set = function (key, data, expire) {
      expire = expire || new this.Expire(30, this.EXPIRE_UNIT.DAY)
      const value = JSON.stringify({
        data, expire: expire.expireDate
      })
      if (supportWechatMiniProgram) {
        return Wechat['setStorageSync'](key, value)
      } else if (supportAlipayMiniProgram) {
        return Alipay['setStorageSync']({key, data: value})
      } else if (supportLocalStorage) {
        return LocalStorage['setItem'](key, value)
      } else {
        return Cookies['set'](key, value, {expires: 365})
      }
    }

    this.get = function (key) {
      let value = null
      if (supportWechatMiniProgram) {
        value = Wechat['getStorageSync'](key)
      } else if (supportAlipayMiniProgram) {
        const res = Alipay['getStorageSync']({key})
        value = (res && res.data) || null
      } else if (supportLocalStorage) {
        value = LocalStorage['getItem'](key)
      } else {
        value = Cookies['get'](key)
      }
      const _package = JSON.parse(value || '{}')
      if (Date.now() < _package.expire) {
        return _package.data
      }
      this.remove(key)
      return null
    }

    this.remove = function (key) {
      if (supportWechatMiniProgram) {
        return Wechat['removeStorageSync'](key)
      } else if (supportAlipayMiniProgram) {
        return Alipay['removeStorageSync']({key})
      } else if (supportLocalStorage) {
        return LocalStorage['removeItem'](key)
      } else {
        return Cookies['remove'](key)
      }
    }

    this.checkMemory = function () {
      if (supportWechatMiniProgram) {
        Wechat[KEY_MEMORY] = Wechat[KEY_MEMORY] || {}
      } else if (supportAlipayMiniProgram) {
        Alipay[KEY_MEMORY] = Alipay[KEY_MEMORY] || {}
      } else if (supportWindowMemory) {
        window[KEY_MEMORY] = window[KEY_MEMORY] || {}
      } else {
        throw new Error('当前环境不支持缓存至内存')
      }
    }

    this.setMemory = function (key, data, expire) {
      expire = expire || new this.Expire(30, this.EXPIRE_UNIT.DAY)
      const value = JSON.stringify({
        data, expire: expire.expireDate
      })
      this.checkMemory()
      if (supportWechatMiniProgram) {
        Wechat[KEY_MEMORY][key] = value
      } else if (supportAlipayMiniProgram) {
        Alipay[KEY_MEMORY][key] = value
      } else if (supportWindowMemory) {
        window[KEY_MEMORY][key] = value
      }
    }

    this.getMemory = function (key) {
      let value = null
      this.checkMemory()
      if (supportWechatMiniProgram) {
        value = Wechat[KEY_MEMORY][key]
      } else if (supportAlipayMiniProgram) {
        value = Alipay[KEY_MEMORY][key]
      } else if (supportWindowMemory) {
        value = window[KEY_MEMORY][key]
      }
      const _package = JSON.parse(value || '{}')
      if (Date.now() < _package.expire) {
        return _package.data
      }
      this.removeMemory(key)
      return null
    }

    this.removeMemory = function (key) {
      this.checkMemory()
      if (supportWechatMiniProgram) {
        Wechat[KEY_MEMORY][key] = undefined
      } else if (supportAlipayMiniProgram) {
        Alipay[KEY_MEMORY][key] = undefined
      } else if (supportWindowMemory) {
        window[KEY_MEMORY][key] = undefined
      }
    }
  }
}

module.exports = new Storage()
